// NV.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "nvapi.h"
#include <stdio.h>
#include <conio.h> 
#include <Windows.h>

#pragma comment (lib,"nvapi.lib")

int main(int argc, char* argv[])
{
	NvAPI_Status ret = NVAPI_OK;
	int i = 0;

	NV_DISPLAY_DRIVER_MEMORY_INFO MemoryInfo;
	NvAPI_ShortString vBIOS;
	NV_GPU_CLOCK_FREQUENCIES freq;

	memset(&MemoryInfo, 0, sizeof(MemoryInfo));
	MemoryInfo.version = NV_DISPLAY_DRIVER_MEMORY_INFO_VER_1;
	
	memset(&freq, 0, sizeof(freq));

	NvDisplayHandle hDisplay_a[NVAPI_MAX_PHYSICAL_GPUS * 2] = { 0 };

	freq.ClockType = NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ;
	freq.version = NV_GPU_CLOCK_FREQUENCIES_VER_2;

	ret = NvAPI_Initialize();

	if (ret != NVAPI_OK) {
		NvAPI_ShortString string;
		NvAPI_GetErrorMessage(ret, string);
		printf("NVAPI NvAPI_Initialize: %s\n", string);
	}

	NvAPI_ShortString ver;

	NvAPI_GetInterfaceVersionString(ver);
	printf("NVAPI Version: %s\n", ver);

///////////////////////////////////////////////////////////////////////////////

	NvU32 cnt;

	NvPhysicalGpuHandle phys;

	ret = NvAPI_EnumPhysicalGPUs(&phys, &cnt);

	if (ret != NVAPI_OK) {
		NvAPI_ShortString string;
		NvAPI_GetErrorMessage(ret, string);
		printf("NVAPI NvAPI_EnumPhysicalGPUs: %s\n", string);
	}

	NvAPI_ShortString name;

	NV_GPU_THERMAL_SETTINGS thermal;

	ret = NvAPI_GPU_GetFullName(phys, name);
	if (ret != NVAPI_OK) {
		NvAPI_ShortString string;
		NvAPI_GetErrorMessage(ret, string);
		printf("NVAPI NvAPI_GPU_GetFullName: %s\n", string);
	}

	printf("Device name: %s\n", name);

//////////////////////////////////////////////////////////////////////////////

	ret = NvAPI_GPU_GetMemoryInfo(phys, &MemoryInfo);
	if (ret ==NVAPI_OK){
		printf("GPU memory: %dM\n", MemoryInfo.dedicatedVideoMemory/1024);
	}

	ret = NvAPI_GPU_GetVbiosVersionString(phys, vBIOS);
	printf("VBIOS version: %s\n", vBIOS);

	thermal.version = NV_GPU_THERMAL_SETTINGS_VER;

	ret = NvAPI_GPU_GetThermalSettings(phys, 0, &thermal);

	if (ret != NVAPI_OK) {
		NvAPI_ShortString string;
		NvAPI_GetErrorMessage(ret, string);
		printf("NVAPI NvAPI_GPU_GetThermalSettings: %s\n", string);
	}
	printf("\rCurrent temperature: %li C\n", thermal.sensor[0].currentTemp);
	
	NvAPI_GPU_GetAllClockFrequencies(phys, &freq);
	if(freq.domain->bIsPresent){
		printf("\rCurrent frequencies: %d MHz\n", freq.domain->frequency/1000);
	}

	return 0;
}

